package com.xzx.ecommercedw.common;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author xinzhixuan
 * @version V1.0.0
 * @date 2019/11/14
 **/
@Slf4j
public final class JsonUtil {
    private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

    /**
     * 将对象转为json字符串
     * @param o .
     * @return .
     */
    public static String toJson(Object o) {
        try {
            return OBJECT_MAPPER.writeValueAsString(o);
        } catch (JsonProcessingException e) {
            log.error("toJson error", e);
            throw new RuntimeException(e);
        }
    }

    /**
     * 将json字符串转换为Bean对象
     * @param jsonStr .
     * @param clazz .
     * @param <T> .
     * @return .
     */
    public static <T> T parseJson(String jsonStr, Class<T> clazz) {
        try {
            return OBJECT_MAPPER.readValue(jsonStr, clazz);
        } catch (IOException e) {
            log.error("parseJson error", e);
            throw new RuntimeException(e);
        }
    }

    /**
     * 将json字符串转为List指定泛型的类型
     * @param jsonStr .
     * @param clazz 泛型类型
     * @param <T> .
     * @return .
     */
    public static <T> List<T> parseListJson(String jsonStr, Class<T> clazz) {
        try {
            JavaType javaType = OBJECT_MAPPER.getTypeFactory().constructParametricType(List.class, clazz);
            return OBJECT_MAPPER.readValue(jsonStr, javaType);
        } catch (IOException e) {
            log.error("parseListJson error", e);
            throw new RuntimeException(e);
        }
    }

    /**
     * 将json字符串转为Map指定泛型的类型
     * @param jsonStr .
     * @param keyClazz 泛型类型
     * @param valueClass 泛型类型
     * @return .
     */
    public static <K, V> Map<K, V> parseMapJson(String jsonStr, Class<K> keyClazz, Class<V> valueClass) {
        try {
            JavaType javaType = OBJECT_MAPPER.getTypeFactory().constructParametricType(HashMap.class, keyClazz, valueClass);
            return OBJECT_MAPPER.readValue(jsonStr, javaType);
        } catch (IOException e) {
            log.error("parseListJson error", e);
            throw new RuntimeException(e);
        }
    }

    /**
     * 将json字符串转换为JsonNode对象,对象只读
     * @param jsonStr .
     * @return .
     */
    public static JsonNode parseJson(String jsonStr) {
        try {
            return OBJECT_MAPPER.readTree(jsonStr);
        } catch (IOException e) {
            log.error("parseJson error, json:{}", jsonStr, e);
            throw new RuntimeException(e);
        }
    }

    /**
     * 将json字符串转为指定类型的数据
     * @param jsonStr
     * @param typeReference
     * @param <T>
     * @return
     */
    public static <T> T parseToTypeReference(String jsonStr, TypeReference<T> typeReference){
        try {
            return OBJECT_MAPPER.readValue(jsonStr, typeReference);
        } catch (IOException e) {
            log.error("parseToTypeReference error, json:{}", jsonStr, e);
            throw new RuntimeException(e);
        }
    }

    public static String asText(JsonNode jsonNode, String key, String defaultValue) {
        JsonNode node = jsonNode.get(key);
        if (node == null){
            return defaultValue;
        } else {
            return node.asText(defaultValue);
        }
    }

    public static Boolean asBoolean(JsonNode jsonNode, String key, Boolean defaultValue) {
        JsonNode node = jsonNode.get(key);
        if (node == null){
            return defaultValue;
        } else {
            return node.asBoolean(defaultValue);
        }
    }

    public static long asLong(JsonNode jsonNode, String key) {
        return asLong(jsonNode, key, 0L);
    }

    public static long asLong(JsonNode jsonNode, String key, long defaultValue) {
        JsonNode node = jsonNode.get(key);
        if (node == null){
            return defaultValue;
        } else {
            return node.asLong(defaultValue);
        }
    }

    /**
   * 获取一个空的ObjectNode
   *
   * @return
   */
  public static ObjectNode createObjectNode() {
    return OBJECT_MAPPER.createObjectNode();
  }

  /**
   * 获取一个空的ArrayNode
   *
   * @return
   */
  public static ArrayNode createArrayNode() {
    return OBJECT_MAPPER.createArrayNode();
  }
}
